#include <iostream>
#include <memory>
#include "net/tcp_server.h"
#include "net/udp_server.h"
#include "net/kcp_server.h"

void runTcpServer() {
    try {
        // 使用 4 个线程（或者 std::thread::hardware_concurrency()）
        size_t num_threads = 4;
        std::cout << "Starting server with " << num_threads << " threads..." << std::endl;

        net::TcpServer server(8080, num_threads);

        // 设置新连接处理函数 (与单线程版本相同，因为连接抽象Connection不变)
        server.setNewConnectionHandler(
                [](net::Connection::Ptr conn) {
                    conn->setCodec(std::make_unique<net::SimpleMessageCodec>());

                    conn->setStateChangeHandler([](net::Connection::Ptr sender, net::ConnectionState state) {
                        switch (state) {
                            case net::ConnectionState::Connected: {
                                std::cout << "New Connected" << std::endl;
                                break;
                            }
                            case net::ConnectionState::Disconnected: {
                                std::cout << "Disconnected" << std::endl;
                                break;
                            }
                        }
                    });
                    conn->setMessageReceiver(
                            [](net::Connection::Ptr sender, const net::Connection::Buffer& msg, size_t length) {
                                // 注意：所有回调现在在各自的 io_context 线程中执行！
                                std::string msgStr = std::string(msg.begin(), msg.end());
                                std::cout << "TID: " << std::this_thread::get_id()
                                          << " | Recv: " << msgStr << std::endl;
                                sender->send("Echo: " + msgStr);
                            });

                    conn->setErrorHandler(
                            [](net::Connection::Ptr, const boost::system::error_code& ec) {
                                if (ec != boost::asio::error::eof) {
                                    std::cerr << "TID: " << std::this_thread::get_id()
                                              << " | Error: " << ec.message() << std::endl;
                                }
                            });
                });

        server.start(); // 启动接受连接和工作线程

    } catch (std::exception& e) {
        std::cerr << "Exception: " << e.what() << std::endl;
    }
}

void runUdpServer() {
    try {
        boost::asio::io_context ioContext;

        // 必须延迟创建 UdpServer，以便传入 appHandler
        net::UdpServer server(ioContext, 9000);

        // --- 核心：使用 Lambda 表达式设置所有回调 ---
        // 1. 设置连接回调 (onConnect)
        server.setConnectCallback([&server](const net::UdpSession& session) {
            std::cout << "\n[EVENT] CONNECT: Session " << session.sessionId
                      << " joined from " << session.clientAddress << std::endl;
            // 立即发送欢迎消息
            std::string welcome = "Welcome, ID: " + std::to_string(session.sessionId);
            server.sendTo(welcome, session.clientEndpoint);
        });

        // 2. 设置断线回调 (onDisconnect)
        server.setDisconnectCallback([](const net::UdpSession& session) {
            std::cout << "[EVENT] DISCONNECT: Session " << session.sessionId
                      << " timed out." << std::endl;
        });

        // 3. 设置消息回调 (onMessage)
        server.setMessageCallback([&server](net::UdpSession& session, const std::string& message, std::size_t size) {
            std::cout << "[EVENT] MESSAGE: Session " << session.sessionId
                      << " (" << size << " bytes) -> " << message.substr(0, std::min((size_t)20, message.size())) << std::endl;

            // 业务逻辑：回送消息 (Echo)
            std::string echo = "ECHO: " + message;
            server.sendTo(echo, session.clientEndpoint);
        });

        // 4. 设置错误回调 (onError)
        server.setErrorCallback([](const boost::system::error_code& ec) {
            std::cerr << "[EVENT] ERROR: Code " << ec.value() << ", " << ec.message() << std::endl;
        });

        // 运行事件循环
        ioContext.run();

    } catch (const std::exception& e) {
        std::cerr << "Fatal Exception: " << e.what() << std::endl;
    }
}


void runKcpServer() {
    try {
        boost::asio::io_context ioContext;

        net::KcpServer server(ioContext, 9000);

        // --- 设置消息回调 ---
        server.setMessageCallback([&server](net::ConvIdType convId, const std::string& message, std::size_t size) {
            std::cout << "[KCP MSG] Conv " << convId
                      << " received: " << message.substr(0, std::min((size_t)1024, message.size())) << std::endl;

            // 业务逻辑：如果需要回复，则通过 KcpSession 实例发送
            // 注意：要实现 Echo，你需要一个获取 KcpSession 实例的方法，这里只是一个概念示例
            auto session = server.getSessionByConvId(convId);

            if (session) {
                std::string echo_message = "KCP ECHO (" + std::to_string(size) + " bytes): " + message;

                // 使用找到的 KcpSession 实例发送可靠消息
                session->send(echo_message);

                std::cout << "[KCP SENT] Echo sent to Conv " << convId << std::endl;
            } else {
                std::cerr << "[KCP ERROR] Session not found for ConvId: " << convId << std::endl;
            }
        });

        // --- 设置错误回调 ---
        server.setErrorCallback([](const boost::system::error_code& ec) {
            std::cerr << "[KCP EVENT] Server Error: " << ec.message() << std::endl;
        });

        ioContext.run();

    } catch (std::exception& e) {
        std::cerr << "Fatal Exception: " << e.what() << std::endl;
    }

}

int main() {
    // runUdpServer();
    runKcpServer();
    return  0;
}